package pl.edu.agh.student.nn.core;

import java.util.ArrayList;
import java.util.List;

/**
 * 
 * To change this template use File | Settings | File Templates.
 *
 */
public class InputOutputNeuron extends Neuron
{

    /**
     * Polaczenia wchodzace do neuronu
     */
    private List<Connection> inputConnections = new ArrayList<Connection>();
    private List<Connection> oldInputConnections = new ArrayList<Connection>();

    /**
     * 
     * Funcja obliczajaca odpowiedz neuronu na podaje wartosci na wejsciach
     * neuronu. Odpowiedz jest obliczana przez zsumowanie iloczynow wag polaczen
     * i poziomu sygnalu a nastepnie przepuszczenie uzyskanej sumy przez funkcje 
     * aktywacji
     *
     */
    @Override
    public void calculate()
    {

        this.setOutput(
                this.getActivationFunction().getResult(
                sumInputs()));
    }

    /**
     * Oblicza sum(ni * wi)
     * 
     * @return 
     */
    public double sumInputs()
    {
        double sum = 0;
        for (Connection c : inputConnections)
        {
            double in = c.getFromNeuron().getOutput();
            double w = c.getWeight();

            sum += in * w;
        }
        sum += this.getBias();
        return sum;
    }

    @Override
    public String display()
    {
        StringBuilder sb = new StringBuilder();
        sb.append(activationFunction.display()).append(" ");
        for (int i = 0; i < inputConnections.size(); i++)
        {
            sb.append(inputConnections.get(i).getWeight()).append(" ");
        }
        return sb.toString();
    }

    public void addConnection(Connection c)
    {
        inputConnections.add(c);

        Connection c1 = new Connection();
        c1.setFromNeuron(c.getFromNeuron());
        c1.setToNeuron(c.getToNeuron());
        c1.setWeight(c.getWeight());

        this.oldInputConnections.add(c1);

    }

    public List<Connection> getInputConnections()
    {
        return inputConnections;
    }

    public List<Connection> getOldInputConnections()
    {
        return oldInputConnections;
    }

    public void setInputConnections(List<Connection> inputConnections)
    {
        this.inputConnections = inputConnections;

        this.oldInputConnections = new ArrayList<Connection>();
        for (Connection c : outputConnections)
        {
            Connection c1 = new Connection();
            c1.setFromNeuron(c.getFromNeuron());
            c1.setToNeuron(c.getToNeuron());
            c1.setWeight(c.getWeight());

            this.oldInputConnections.add(c1);
        }
    }

    public void setConnectionWeight(int i, double weight)
    {
        double old = this.inputConnections.get(i).getWeight();
        this.inputConnections.get(i).setWeight(weight);

        this.oldInputConnections.get(i).setWeight(old);
    }
}
